package io.zhengsh.juc._2synchronized1.status;

import org.openjdk.jol.info.ClassLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.LockSupport;

public class BiasedLockingBulkRebiasTest {

    private static Logger log = LoggerFactory.getLogger(BiasedLockingBulkRebiasTest.class);

    public static void main(String[] args) throws InterruptedException {
        // 延迟产生可偏向对象
        Thread.sleep(5000);

        List<Object> list = new ArrayList<>(50);

        //thread0
        new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                Object lock = new Object();
                synchronized (lock) {
                    list.add(lock);
                }

            }

            // 防止 JVM 线程复用，在创建完对象后，保持 thread0 状态存活
            try {
                Thread.sleep(100000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "thread0").start();

        // 睡眠 3s 保证thread0 创建对象完成
        Thread.sleep(5000);
        log.debug("list 中第 20 个对象的对象头");
        log.debug((ClassLayout.parseInstance(list.get(19)).toPrintable()));

        //thread1
        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                Object obj = list.get(i);

                synchronized (obj) {
                    if (i >= 15 && i <= 40) {
                        log.debug("thread1‐第" + (i + 1) + "次加锁执行中\t" +
                                ClassLayout.parseInstance(obj).toPrintable());
                    }
                }
                if (i == 17 || i == 19) {
                    log.debug("thread1‐第" + (i + 1) + "次释放锁\t" +
                            ClassLayout.parseInstance(obj).toPrintable());
                }
            }

            // 防止 JVM 线程复用，在创建完对象后，保持 thread0 状态存活
            try {
                Thread.sleep(100000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }, "thread1").start();

        LockSupport.park();
    }
}
